package com.zzyl.nursing.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huaweicloud.sdk.iotda.v5.IoTDAClient;
import com.huaweicloud.sdk.iotda.v5.model.ServiceCapability;
import com.huaweicloud.sdk.iotda.v5.model.ServiceProperty;
import com.huaweicloud.sdk.iotda.v5.model.ShowProductRequest;
import com.huaweicloud.sdk.iotda.v5.model.ShowProductResponse;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.common.utils.UserThreadLocal;
import com.zzyl.nursing.domain.Device;
import com.zzyl.nursing.domain.DeviceData;
import com.zzyl.nursing.domain.Elder;
import com.zzyl.nursing.domain.FamilyMemberElder;
import com.zzyl.nursing.dto.DeviceDto;
import com.zzyl.nursing.dto.MemberElderDto;
import com.zzyl.nursing.mapper.DeviceDataMapper;
import com.zzyl.nursing.mapper.FamilyMemberElderMapper;
import com.zzyl.nursing.service.IDeviceDataService;
import com.zzyl.nursing.service.IDeviceService;
import com.zzyl.nursing.service.IElderService;
import com.zzyl.nursing.service.IFamilyMemberElderService;
import com.zzyl.nursing.vo.DeviceDataGraphVo;
import com.zzyl.nursing.vo.FamilyMemberElderVo;
import com.zzyl.nursing.vo.MemberElderVo;
import com.zzyl.nursing.vo.PropertyStatusInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

/**
 * @Description FamilyMemberElderService
 * @Author LaiShidong
 * @Date 2025-03-02  16:17
 */
@Service
@Slf4j
public class FamilyMemberElderServiceImpl extends ServiceImpl<FamilyMemberElderMapper, FamilyMemberElder>
        implements IFamilyMemberElderService {

    @Autowired
    private IElderService elderService;
    @Autowired
    private FamilyMemberElderMapper familyMemberElderMapper;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private IDeviceService deviceService;
    @Autowired
    private IoTDAClient client;
    @Autowired
    private DeviceDataMapper deviceDataMapper;

    /**
     * 小程序绑定家人
     *
     * @param memberElderDto
     */
    @Override
    public void addFamily(MemberElderDto memberElderDto) {

        FamilyMemberElder familyMemberElder = new FamilyMemberElder();

        // 获取当前小程序登录家属id
        Long userId = UserThreadLocal.getUserId();

        // 根据老人身份证查询老人id
        Elder elder = elderService.getOne(new LambdaQueryWrapper<Elder>().
                eq(Elder::getIdCardNo, memberElderDto.getIdCard())
                .eq(Elder::getName, memberElderDto.getName()));

        if (ObjectUtil.isEmpty(elder)) {
            throw new BaseException("绑定家人失败，家属信息有误");
        }

        // 是否已经绑定
        long count = count(new LambdaQueryWrapper<FamilyMemberElder>().eq(FamilyMemberElder::getFamilyMemberId, userId)
                .eq(FamilyMemberElder::getElderId, elder.getId()));

        if (count > 0) {
            throw new BaseException("已经绑定了，请不要重复绑定");
        }

        // 封装familyMemberElder对象
        familyMemberElder.setFamilyMemberId(userId);
        familyMemberElder.setElderId(elder.getId());
        familyMemberElder.setRemark(memberElderDto.getRemark());

        save(familyMemberElder);
    }

    /**
     * 小程序查询家人列表
     *
     * @return
     */
    @Override
    public List<FamilyMemberElderVo> queryFamily() {

        List<FamilyMemberElder> familyMemberElders = list(new LambdaQueryWrapper<FamilyMemberElder>()
                .eq(FamilyMemberElder::getFamilyMemberId, UserThreadLocal.getUserId()));

        if (CollectionUtil.isEmpty(familyMemberElders)) {
            return Collections.emptyList();
        }

        List<FamilyMemberElderVo> familyMemberElderVos = new ArrayList<>();
        familyMemberElders.forEach(familyMemberElder -> {
            FamilyMemberElderVo familyMemberElderVo = BeanUtil.toBean(familyMemberElder, FamilyMemberElderVo.class);
            familyMemberElderVos.add(familyMemberElderVo);
        });

        return familyMemberElderVos;
    }

    /**
     * 小程序分页查询家人列表
     *
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public List<MemberElderVo> pageList(Integer pageNum, Integer pageSize) {

        // 分页开始参数
        Integer pageNo = (pageNum - 1) * pageSize;
        Long userId = UserThreadLocal.getUserId();

        List<MemberElderVo> list = familyMemberElderMapper.pageList(userId, pageNo, pageSize);
        if (CollectionUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        return list;
    }

    /**
     * 查询健康数据
     *
     * @param deviceDto
     */
    @Override
    public Map<String, Map<String, Object>> queryDevicePropertyStatus(DeviceDto deviceDto) {

        // 根据设备名获取iot-id
        Device device = deviceService.getOne(new LambdaQueryWrapper<Device>()
                .eq(Device::getDeviceName, deviceDto.getDeviceName()));


        Object dataOjb = redisTemplate.opsForHash().get(CacheConstants.IOT_DEVICE_LAST_DATA, device.getIotId());

        List<DeviceData> deviceDataList = JSONUtil.toList((JSONUtil.toJsonStr(dataOjb)), DeviceData.class);


        List<PropertyStatusInfo> PropertyStatusInfos = new ArrayList<>();

        // 根据"productKey" 查询data_type
        ShowProductRequest request = new ShowProductRequest();
        request.withProductId(deviceDto.getProductKey());
        ShowProductResponse response = null;
        try {
            response = client.showProduct(request);
        } catch (Exception e) {
            log.error("获取产品失败，原因：{}", e.getMessage());
            e.printStackTrace();
            throw new RuntimeException("物联网平台-同步产品失败");
        }

        if (response.getHttpStatusCode() != 200) {
            log.error("获取产品失败");
            throw new RuntimeException("物联网平台-同步产品失败");
        }
        List<ServiceCapability> serviceCapabilities = response.getServiceCapabilities();

        if (CollectionUtil.isEmpty(serviceCapabilities)) {
            throw new RuntimeException("该产品为设置属性");
        }
        serviceCapabilities.forEach(serviceCapability -> {
            List<ServiceProperty> properties = serviceCapability.getProperties();

            properties.forEach(p -> {
                String unit = p.getUnit();
                String dataType = p.getDataType();
                String propertyName = p.getPropertyName();
                deviceDataList.forEach(deviceData -> { // 测试使用已经写死，所有数据都是心率的数据
                    if ("HeartRate".equals(deviceData.getFunctionId())) {
                        PropertyStatusInfo propertyStatusInfo = new PropertyStatusInfo();
                        propertyStatusInfo.setIdentifier(deviceData.getFunctionId());
                        LocalDateTime alarmTime = deviceData.getAlarmTime();
                        long milli = LocalDateTimeUtil.toEpochMilli(alarmTime);
                        propertyStatusInfo.setTime(milli);
                        propertyStatusInfo.setValue(deviceData.getDataValue());
                        propertyStatusInfo.setName(p.getDescription());
                        propertyStatusInfo.setUnit(unit);
                        propertyStatusInfo.setDataType(dataType);

                        PropertyStatusInfos.add(propertyStatusInfo);

                    }
                });
            });

        });

        Map<String, Object> map = new HashMap<>();
        map.put("propertyStatusInfo", PropertyStatusInfos);

        Map<String, Map<String, Object>> mapVo = new HashMap<>();
        mapVo.put("list", map);
        return mapVo;
    }

    /**
     * 按天统计查询指标数据
     *
     * @param functionId
     * @param startTime
     * @param endTime
     * @param iotId
     * @return
     */
    @Override
    public List<DeviceDataGraphVo> queryDeviceDataListByDay(String functionId, Long startTime, Long endTime, String iotId) {
        LocalDateTime localDateTimeStart = LocalDateTimeUtil.of(startTime);
        LocalDateTime localDateTimeEnd = LocalDateTimeUtil.of(endTime);

        List<DeviceDataGraphVo> deviceDataGraphVos = DeviceDataGraphVo.dayInstance(localDateTimeStart);
        List<DeviceDataGraphVo> deviceDataGraphDbs = deviceDataMapper.queryDeviceDataList(functionId, localDateTimeStart, localDateTimeEnd, iotId);

        deviceDataGraphVos.forEach(deviceDataGraphVo->{
            deviceDataGraphDbs.forEach(deviceDataGraphDb->{
                if (Objects.equals(deviceDataGraphVo.getDateTime(), deviceDataGraphDb.getDateTime())){
                    deviceDataGraphVo.setDataValue(deviceDataGraphDb.getDataValue());
                }
            });

        });
        return deviceDataGraphVos;
    }

    /**
     * 按周统计查询指标数据
     *
     * @param functionId
     * @param startTime
     * @param endTime
     * @param iotId
     * @return
     */
    @Override
    public List<DeviceDataGraphVo> queryDeviceDataListByWeek(String functionId, Long startTime, Long endTime, String iotId) {
        LocalDateTime localDateTimeStart = LocalDateTimeUtil.of(startTime);
        LocalDateTime localDateTimeEnd = LocalDateTimeUtil.of(endTime);
        List<DeviceDataGraphVo> deviceDataGraphVos = DeviceDataGraphVo.weekInstance(localDateTimeStart);

        List<DeviceDataGraphVo> deviceDataGraphDbs =  deviceDataMapper.queryDeviceDataListByWeek(localDateTimeStart,localDateTimeEnd,functionId,iotId);

        deviceDataGraphVos.forEach(deviceDataGraphVo->{
            deviceDataGraphDbs.forEach(deviceDataGraphDb->{
                String dateTimeDb = deviceDataGraphDb.getDateTime();

                String[] split = dateTimeDb.split("-");
                String dateTime = split[1]+"."+split[2];

                String dateTimeVo = deviceDataGraphVo.getDateTime();

                if (Objects.equals(dateTime, dateTimeVo)){
                    deviceDataGraphVo.setDataValue(deviceDataGraphDb.getDataValue());
                }
            });

        });

        return deviceDataGraphVos;
    }
}
